let id = 0
let running = new Map()

function create() {
    const worker = new Worker(new URL('./thread.worker.js', import.meta.url), {
        type: 'module'
    })
    worker.onmessage = function (evt) {
        const { id, event, data } = evt.data
        const ops = running.get(id)
        if (ops) {
            if (event) {
                ops[event]?.call(ops, data)
            } else {
                running.delete(id)
                const { resolve, reject } = ops
                if (data instanceof Error) {
                    reject(data)
                } else {
                    resolve(data)
                }
            }
        }
    }
    return worker
}

export function run(module, command, data, options) {
    const { timeout, standalone = true, onProgress } = options || {}

    const worker = standalone ? create() : defaultWorker
    return new Promise((resolve, reject) => {
        let timeoutId
        if (timeout) {
            timeoutId = setTimeout(() => {
                running.delete(command)
                reject(new Error(command + '取消执行'))
            }, timeout)
        }
        id++
        worker.postMessage({
            id,
            command,
            data,
            module
        })
        running.set(id, {
            resolve: data => {
                timeoutId && clearTimeout(timeoutId)
                standalone && worker.postMessage('close')
                resolve(data)
            },
            reject: error => {
                timeoutId && clearTimeout(timeoutId)
                standalone && worker.postMessage('close')
                reject(error)
            },
            onProgress
        })
    })
}
